调用
函数的调用非常简单,python
提供了很多内置函数供我们使用,比如:
获取绝对值:
1 | >>> abs(-123) |
求多个数中的最大值:
1 | >>> max(1, 2, 3) |
求多个数中的最小值:
1 | >>> min(0, -1, 99) |
类型转换
1 | >>> int('123') |
以上的方法和形式与Swift
语言十分相似,abs()函数
、max()函数
、min()函数
甚至和Swift
的API
一模一样,包括形式和用法。
再比如,python
也提供了hex()函数
将一个整数
(注意:必须是整数,否则就会报错)转换成一个十六进制表示的字符串
。比如:
1 | >>> hex(22) |
定义
使用def
定义函数
例如,创建一个demo.py
文件,定义一个test(a, b)
函数,并传入参数:
1 | def test(a, b): |
执行:
1 | python3 demo.py |
输出结果:
1 | a < b |
注意:我们也可以在当前目录下,进入
python交互式环境
,然后使用from demo import test
的形式导出该demo.py
里面具体函数,demo
是文件名,注意没有.py
后缀,test
是函数名,然后在交互式环境下使用test(a, b)
函数。
pass
占位符
有时候,我们可以在函数或一些程序中使用pass
来作为占位符,比如定义一个函数,但是里面没有任何内容,执行就会报错,比如:
1 | def fuck(): |
执行:
1 | python3 demo.py |
报错:
1 | ➜ Desktop python3 demo.py |
那想留住这个函数,后面在写函数体里面的内容怎么办呢?有2种
方式,第一,使用pass
,第二,使用return
,例如:
1 | def fuck(): |
或者
1 | def fuck(): |
这样执行python文件
,就可以执行里面的程序而不会因为一个空函数
而报错。
类型检查
数据类型检查直接使用内置函数isinstance()函数
,例如:
1 | def test1(a): |
1 | >>> from demo import test1 |
函数返回多个值
python
的函数返回多个值的时候,事实上是返回一个元组(tuple
),例如:
1 | def func1(a, b): |
执行:
1 | ➜ Desktop python3 |
参数
位置参数
位置参数就是正常的参数传递,别想复杂了,例如:
1 | def fuckYou(name): |
在上面的fuckYou函数
中,name
就是所谓的位置参数。
默认参数
默认参数就是在函数调用的时候,给部分参数设置一个默认的初始值的参数。这个其实也很好理解,现在很多语言都提供默认参数了,比如JavaScript
、Swift
等等,默认参数在有的时候可以简化我们的代码。例如:
1 | def fuck(name, gender = 'girl', age = 18): |
1 | >>> from demo import fuck |
注:在
python
中,当提供多个默认参数,并且在调用的时候,如果不按顺序调用后面的某个默认参数,就需要指定需要改变的那个默认参数名,比如上面的调用fuck('Joe', age = 38)
,需要改变默认参数age
的值,但是默认参数age
前面的默认参数gender
保持不变(继续使用默认参数值),那么就需要指定age
这个参数名,否则,直接传入参数的话,在函数内部就会一一对应。
另外,当使用默认参数的时候,也要注意,一般情况下,默认参数尽量是不可变参数值,如果是可变的话(比如数组,数组是一个引用类型对象),那么就会造成数据修改。例如:
1 | def appendElement(arr = []): |
执行结果:
1 | >>> from demo import appendElement |
当然,我们也可以使用None
空值来改造一下可变的对象参数:
1 | def appendElement(arr = None): |
执行结果:
1 | >>> appendElement() |
因此,为了安全起见,建议一般默认参数都是用不可变对象,如果非要使用可变对象,一定要做好安全检查。
可变参数
可变参数就是可以传入任意个数参数,对参数不限制。在python
中,可变参数可以在参数名前面加*
号来表示这个一个可变参数,传入的可变参数在内部会转换成一个元组(tuple)。例如:
1 | def sum(*params): |
执行:
1 | >>> from demo import sum |
那如果我们要传入一个数组或元组将其中的元素作为可变参数传入怎么办呢?同样地,我们还是可以在要传入的数组或元组前面加*
号,表示将数组或元组中的元素作为可变参数。例如:
1 | >>> sum(*[1, 2, 3]) |
哇,就是这么吊!
关键字参数
关键字参数在参数名前面加**
表示可传入一个关键字参数,传入关键字参数后,内部会组装成一个字典(dict)。例如:
1 | def obtainInfo(name, age, **params): |
执行:
1 | >>> obtainInfo('langke', 18) |
类似地,我们也可以在字典(dict)前面加**
作为关键字参数传入:
1 | dicParams = { |
我们也可以对关键字参数进行判断某个key
是否存在,例如:
1 | def person(name, age, **params): |
执行及结果:
1 | ➜ Desktop python3 demo.py |
命名关键字参数
命名关键字参数使用*
号来分割前后参数,*
号后面的参数就叫做命名关键字参数。例如:
1 | def person(name, age, *, city, height): |
其中,city
和height
就是命名关键字参数,而且所有的命名关键字参数必须指定传入值。例如:
1 | >>> person('langke', 18, city = 'Hangzhou', height = 163) |
如果少了某个关键字参数,就会报错。例如:
1 | >>> person('langke', 18, city = 'Hangzhou') |
关键字参数可以互换位置,但是必须要注意的是,关键字参数和关键字参数前面的位置参数不能调换。例如:
关键字参数city
和height
交换位置:
1 | >>> person('langke', 18, height = 163, city = 'Hangzhou') |
关键字参数和位置参数交换位置,比如把关键字参数height
放在位置参数age
位置就报错:
1 | >>> person('langke', height = 163, 18, city = 'Hangzhou') |
若函数中已经有可变参数,那么命名关键字参数就不再需要*
号了。例如:
1 | def person(name, age, *args, city, height): |
调用函数:
1 | >>> person('langke', 18, city = 'Hangzhou', height = 163) |
最后,命名关键字参数可以有默认值(类似默认参数)。例如:
1 | def person(name, age, *, city = 'Hangzhou', height): |
执行:
1 | >>> person('langke', 18, height = 163) |
参数组合
参数组合也就是使用位置参数、默认参数、可变参数、命名关键字参数、关键字参数结合起来使用,但是参数定义的顺序必须是:位置参数、默认参数、可变参数、命名关键字参数、关键字参数。例如:
1 | def f1(a, b, c=0, *args, **kw): |
调用:
1 | >>> f1(1, 2) |
最后一点要注意的是,调用上面的函数我们也可以只使用元组(tuple)
和数组(list)
的方式传入参数:
1 | >>> args = (1, 2, 3, 4) |
所以,对于任意函数,都可以通过类似func(*args, **kw)
的形式调用它,无论它的参数是如何定义的。
递归
递归函数就是自己调用自己的函数。例如:
1 | def sum(n): |
执行:
1 | >>> sum(5) |
小结
python
的函数其实和其他编程语言都大同小异,需要注意的一点是函数参数的顺序,尤其是当我们使用组合参数时,一不小心很容易出错。